
#-*- coding: utf-8 -*-
import requests
import json
import urllib
import sys,os
import re
from bs4 import BeautifulSoup
class Music_tx():
    def __init__(self):
        self.header = {
            'Connection': "keep-alive",
            'Pragma': "no-cache",
            'Cache-Control': "no-cache",
            'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
                          "Chrome/72.0.3626.119 Safari/537.36",
            'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
            'Referer': "https://y.qq.com",
            'Accept-Encoding': "gzip, deflate, br",
            'Accept-Language': "zh-CN,zh;q=0.9",
            'cache-control': "no-cache",
        }
 
    # 显示下载进度
    def _progress(self, block_num, block_size, total_size):
        '''回调函数
           @block_num: 已经下载的数据块
           @block_size: 数据块的大小
           @total_size: 远程文件的大小
        '''
        sys.stdout.write('\r>> 已下载: %.1f%%' % (int(block_num * block_size) / int(total_size) * 100.0))
        sys.stdout.flush()
    #通过json接口搜索音乐
    def search_music(self,keyword,num = 2,page = 1,file_path = None):
        url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=62240638881390953&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p='+str(page)+'&n='+str(num)+'&w='+str(keyword)+'&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0'
        response= requests.get(url, headers=self.header)
        music_data = response.text
        json_music_data = json.loads(music_data)
        music_list = json_music_data['data']['song']['list']
        song_mids = []
        song_titles = []
        song_singers = []
        num = 0
        if not file_path:
            file_path = os.path.dirname(os.path.abspath(__file__)) + '\\'
            if not os.path.isdir(file_path + 'mp3'):
                os.mkdir(file_path + 'mp3')
            file_path = os.path.dirname(os.path.abspath(__file__)) + '\\mp3\\'
        for data in music_list:
            try:
                song_mids.append(data['mid'])
                song_titles.append(data['title'])
                song_singers.append(data['singer'][0]['name'])
                print('正在下载:', data['title'], '......')
                get_url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data={"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"8348972662","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"8348972662","songmid":["'+data['mid']+'"],"songtype":[1],"uin":"0","loginflag":1,"platform":"20"}},"comm":{"uin":0,"format":"json","ct":24,"cv":0}}'
                response = requests.get(get_url)
                sip = json.loads(response.text)['req']['data']['sip'][0]
                purl = json.loads(response.text)['req_0']['data']['midurlinfo'][0]['purl']
                real_url = sip + purl
                if os.path.isfile(file_path + data['title']+'-'+ data['singer'][0]['name'] + '.m4a'):
                    num += 1
                    path = file_path + data['title'] + '-' + data['singer'][0]['name'] + str(num) + '.m4a'
                else:
                    path = file_path + data['title'] + '-' + data['singer'][0]['name'] + '.m4a'
                try:
                    urllib.request.urlretrieve(real_url,path,reporthook=self._progress)
                    print('下载' + data['title'] + '成功')
                except Exception:
                    print('下载' +data['title'] + '失败')
                    print(str(Exception))
            except:
                print('wrong')
        print("下载完成")
 
    #获取播放地址
    def get_play_url(self,songid,strMediaMid):
        url = 'https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?&jsonpCallback=MusicJsonCallback&cid=205361747&songmid=' +\
               songid+ '&filename=C400' +strMediaMid+ '.m4a&guid=6612300644'
        # 获取返回文件并解析得到vkey
        response = requests.get(url)
        json_data = json.loads(response.text)
        vkey = json_data['data']['items'][0]['vkey']
        real_url = 'http://isure.stream.qqmusic.qq.com/C400' + strMediaMid + '.m4a?vkey=' + vkey + '&guid=6612300644&uin=0&fromtag=66'
        #print(real_url)
        return real_url
    #通过网址直接下载
    def down_music(self,url,file_path = None):
        t = re.compile('\w+')
        songmid = t.findall(url)[7]
        get_url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data={"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"8348972662","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"8348972662","songmid":["'+songmid+'"],"songtype":[1],"uin":"0","loginflag":1,"platform":"20"}},"comm":{"uin":0,"format":"json","ct":24,"cv":0}}'
        response = requests.get(get_url)
        sip = json.loads(response.text)['req']['data']['sip'][0]
        purl = json.loads(response.text)['req_0']['data']['midurlinfo'][0]['purl']
        real_url = sip + purl
        res = requests.get(url)
        soup = BeautifulSoup(res.content, 'html.parser')
        title = soup.find('h1', attrs={'class': 'data__name_txt'}).text
        singer = (soup.find('div', attrs={'class': 'data__singer'}).text).replace('\n','')
        num = 0
        if not file_path:
            file_path = os.path.dirname(os.path.abspath(__file__)) + '\\'
            if not os.path.isdir(file_path + 'mp3'):
                os.mkdir(file_path + 'mp3')
            file_path = os.path.dirname(os.path.abspath(__file__)) + '\\mp3\\'
        if os.path.isfile(file_path + title + '-' + singer + '.m4a'):
            num += 1
            path = file_path + title + '-' + singer + str(num) + '.m4a'
        else:
            path = file_path + title + '-' + singer + '.m4a'
        try:
            urllib.request.urlretrieve(real_url, path, reporthook=self._progress)
            print('下载' + title + '成功')
        except Exception:
            print('下载' + title + '失败')
 
    def inputmusicname(self):
        inp = input("输入要下载的歌曲名称：")
        self.search_music(inp)#通过搜索下载
if __name__ == '__main__':
    qq_music = Music_tx()
    # url = 'https://y.qq.com/n/yqq/song/0020stYG1RLye8.html'
    # qq_music.down_music(url)#通过网址下载
    qq_music.inputmusicname()